package com.lysj.admin.master.common.resolver;

import cn.hutool.json.JSONUtil;
import com.lysj.admin.master.common.CommonConstant;
import com.lysj.admin.master.common.annotation.TokenInfo;
import com.lysj.admin.master.common.exception.BaseException;
import com.lysj.admin.master.common.jwt.JwtUtil;
import com.lysj.admin.master.common.web.ParamUtil;
import com.lysj.admin.master.common.web.Resp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import java.util.HashMap;
import java.util.Map;

/**
 * @author Created by zk on 2019-05-16 15:47
 * @description
 */
@Slf4j
@Component
public class TokenInfoResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        return methodParameter.hasParameterAnnotation(TokenInfo.class);
    }

    @Override
    @SuppressWarnings("unchecked")
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        TokenInfo tokenInfo = methodParameter.getParameterAnnotation(TokenInfo.class);
        Map<String, Object> payloadMap;
        payloadMap = (Map<String, Object>) nativeWebRequest.getAttribute(CommonConstant.JWT_PAYLOAD_KEY, RequestAttributes.SCOPE_REQUEST);
        if (payloadMap == null) {
            String token = nativeWebRequest.getHeader(tokenInfo.headName());
            if (ParamUtil.isBlank(token)) {
                throw new BaseException(Resp.ResStatus.PARAM_ERROR, "token有误");
            }
            payloadMap = JwtUtil.getPayloadMap(token);
        }
        if (tokenInfo.allProperty()) {
            return JSONUtil.toJsonStr(payloadMap);
        }
        if (tokenInfo.value().length == 1) {
            return payloadMap.get(tokenInfo.property()[0]);
        } else {
            Map<String, Object> res = new HashMap<>(tokenInfo.value().length);
            for (String s : tokenInfo.value()) {
                res.put(s, payloadMap.get(s));
            }
            return JSONUtil.toJsonStr(res);
        }
    }
}
